package Client

import (
	"Student_Mental/DBconfing"
	"Student_Mental/controller/wsService"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"strconv"
	"time"
)

// GetOrCreateRoomId
// @Tags 聊天室
// @summary 在mysql检查聊天室
// @Param uid1 formData string false "用户1Id"
// @Param uid2 formData string false "用户2Id"
// @Router /public/client/check/room [post]
func GetOrCreateRoomId(c *gin.Context) {
	sqlDb, _ := DBconfing.Mysql()
	defer sqlDb.Close()
	uid1, _ := strconv.Atoi(c.PostForm("uid1"))
	uid2, _ := strconv.Atoi(c.PostForm("uid2"))
	var roomId int
	// 预处理 SQL 语句
	stmt, err := sqlDb.Prepare("CALL get_or_create_room_id(?, ?, @roomid);")
	if err != nil {
		fmt.Println(err)
		return
	}
	// 执行语句
	_, err = stmt.Exec(uid1, uid2)
	if err != nil {
		fmt.Println(err)
		c.JSON(200, gin.H{
			"code": 403,
			"err":  err.Error(),
		})
		return
	}
	err = sqlDb.QueryRow("SELECT @roomid").Scan(&roomId)
	if err != nil {
		fmt.Println(err)
		c.JSON(200, gin.H{
			"code": 403,
			"err":  err.Error(),
		})
		return
	}
	c.JSON(200, gin.H{
		"code":   200,
		"roomId": roomId,
	})
}

// GetMessages
// @Tags 聊天室
// @summary 根据RoomID获取聊天记录
// @Param RoomId path string false "用户1Id"
// @Router /public/client/GetMessage/{RoomId} [get]
func GetMessages(c *gin.Context) {
	red, _ := DBconfing.ConnRedis()
	defer red.Close()
	RoomId := c.Param("RoomId")

	// 检查 RoomId 是否存在
	exists, err := red.Exists(RoomId).Result()
	if err != nil {
		panic(err)
		return
	}

	// 如果不存在就从sql中同步前100条
	if exists != 1 {
		M := wsService.Message{}
		var id int
		sql, _ := DBconfing.Mysql()
		defer sql.Close()
		rows, err := sql.Query("SELECT * FROM `message` WHERE roomId = ? order by SendTimestamp DESC LIMIT 100", RoomId)
		if err != nil {
			panic(err)
			return
		}
		for rows.Next() {

			rows.Scan(&id, &M.RoomId, &M.Sender, &M.SenderName, &M.Recipient, &M.Content, &M.SendTime, &M.Type, &M.SendTimestamp)
			t, _ := time.Parse("2006-01-02T15:04:05-07:00", M.SendTime)
			M.SendTime = t.Format("2006-01-02 15:04:05")
			jsonData, _ := json.Marshal(M)
			red.RPush(RoomId, string(jsonData))
		}
	}
	messages, err := red.LRange(RoomId, 0, 10).Result()
	if err != nil {
		fmt.Println(err)
	}
	c.JSON(200, gin.H{
		"data": messages,
	})
}

func GetMoreMessage(c *gin.Context) {
	red, _ := DBconfing.ConnRedis()
	defer red.Close()
	RoomId := c.PostForm("RoomId")
	MessageCount, err := strconv.ParseInt(c.PostForm("MessageCount"), 10, 64)
	if err != nil {
		return
	}
	var messages []string
	messages, _ = red.LRange(RoomId, MessageCount, MessageCount+19).Result()
	//从redis中查出来的聊天记录小于10条就去mysql中同步100条
	if len(messages) < 20 {
		sqlM := wsService.Message{}
		var id int
		sql, _ := DBconfing.Mysql()
		defer sql.Close()

		//redis获取中最后一条的时间 redM.SendTimestamp
		redM := wsService.Message{}
		lastItem, err := red.LIndex(RoomId, -1).Result()
		if err != nil {
			return
		}
		json.Unmarshal([]byte(lastItem), &redM)

		//从数据库中查询比 redM.SendTimestamp 小的记录 同步前100条到redis中
		rows, err := sql.Query("SELECT * FROM `message` WHERE roomId = ? AND SendTimestamp < ? order by SendTimestamp DESC LIMIT 100", RoomId, redM.SendTimestamp)
		if err != nil {
			return
		}
		for rows.Next() {
			rows.Scan(&id, &sqlM.RoomId, &sqlM.Sender, &sqlM.SenderName, &sqlM.Recipient, &sqlM.Content, &sqlM.SendTime, &sqlM.Type, &sqlM.SendTimestamp)
			t, _ := time.Parse("2006-01-02T15:04:05-07:00", sqlM.SendTime)
			sqlM.SendTime = t.Format("2006-01-02 15:04:05")
			jsonData, _ := json.Marshal(sqlM)
			red.RPush(RoomId, string(jsonData))
		}
		messages, _ = red.LRange(RoomId, MessageCount, MessageCount+9).Result()
	}
	c.JSON(200, gin.H{
		"data": messages,
	})
}

func GetName(c *gin.Context) {
	red, _ := DBconfing.ConnRedis()
	defer red.Close()
	ClientId := c.Param("ClientId")
	var Name string
	value, _ := red.HGet("Name", ClientId).Result()
	if value != "" {
		Name = value
	} else {
		sqlDb, _ := DBconfing.Mysql()
		defer sqlDb.Close()
		sqlDb.QueryRow("(SELECT student_name FROM student WHERE id = ?)UNION(SELECT teacher_name FROM teacher WHERE id = ?)LIMIT 1;", ClientId, ClientId).Scan(&Name)
		if Name != "" {
			// 将值存储在 hash 中
			err := red.HSet("Name", ClientId, Name).Err()
			if err != nil {
				panic(err)
			}
		}
	}
	c.JSON(200, gin.H{
		"Name": Name,
	})
}
